package com.xtm.exercise.lock;

import com.xtm.common.lock.Lock;
import com.xtm.common.model.SysMenu;
import com.xtm.exercise.lock.base.ILockService;
import com.xtm.exercise.menu.base.IMenuService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Slf4j
@Service
@RequiredArgsConstructor
public class LockService implements ILockService {

    private final IMenuService menuService;

    /**
     * 锁的使用，实现该方法的原子性
     * @param id 菜单 ID
     * @param throwException 是否抛出异常，模拟事务异常
     */
    @Override
    @Lock(key = "#id")
    @Transactional(rollbackFor = Throwable.class)
    public void test (Long id, int sleepSeconds, boolean throwException) {
        log.info("处理参数为 {} 的请求", id);
        // 新增菜单
        addMenu(id);
        // 模拟业务耗时
        sleep(sleepSeconds);
        if (throwException) {
            throw new RuntimeException("模拟异常，让事务回滚");
        }
        // 删除菜单
        menuService.delMenu(id);
        log.info("参数为 {} 的请求处理完成", id);
    }

    /**
     * 新增菜单
     * @param id 菜单ID
     */
    private void addMenu (Long id) {
        SysMenu menu = new SysMenu();
        menu.setId(id);
        menu.setParentId(2L);
        menu.setName("测试新增的菜单");
        menu.setSort(0);
        menu.setType(2);
        menu.setCreateUser("1");
        menuService.addMenu(menu);
    }

    /**
     * 休息一会儿
     * @param seconds 秒
     */
    private void sleep (int seconds) {
        try {
            Thread.sleep(seconds * 1000);
        } catch (InterruptedException e) {
            log.error("中断异常", e);
        }
    }

}
